package jp.syuriken.snsw.terenaibot.format.function;

import java.util.Arrays;
import java.util.logging.Level;

import jp.syuriken.snsw.terenaibot.format.CompileArg;
import jp.syuriken.snsw.terenaibot.format.FormatFunction;
import jp.syuriken.snsw.terenaibot.format.FormatSyntaxException;
import jp.syuriken.snsw.terenaibot.format.PrecompiledSyntaxGroup;

/**
 * TODO snsoftware
 * 
 * @author $Author: snswinhaiku.lo@gmail.com $
 */
public abstract class AbstractFormatFunction implements FormatFunction {
	
	/**
	 * 引数の数チェックを行う。指定した引数の数であるかを調べます
	 * 
	 * @param args 引数の配列
	 * @param compileArg {@link CompileArg} インスタンス
	 * @param funcname 関数名
	 * @param expected 期待する引数の数
	 * @throws FormatSyntaxException 引数が足りません
	 */
	public void checkArgLength(PrecompiledSyntaxGroup[] args, CompileArg compileArg, String funcname, int expected)
			throws FormatSyntaxException {
		if (args.length < expected) {
			throw new FormatSyntaxException(String.format("Function<%s> must be taken %d arg, but got %d args: %s",
					funcname, expected, args.length, Arrays.toString(args)));
		} else if (args.length > expected) {
			compileArg.getLogger().log(
					Level.INFO,
					String.format("Function<%s> must be taken %d arg, but got %d args: %s", funcname, expected,
							args.length, Arrays.toString(args)));
		}
	}
	
	/**
	 * 引数の数チェックを行う。範囲内の引数の数であるかを調べます
	 * 
	 * @param args 引数の配列
	 * @param compileArg {@link CompileArg} インスタンス
	 * @param funcname 関数名
	 * @param min 期待する最少の引数の数。制限なしは-1
	 * @param max 期待する最多の引数の数。制限なしは-1
	 * @throws FormatSyntaxException 引数が足りません
	 */
	public void checkArgLength(PrecompiledSyntaxGroup[] args, CompileArg compileArg, String funcname, int min, int max)
			throws FormatSyntaxException {
		if (args.length < min) {
			throw new FormatSyntaxException(String.format("Function<%s> must be taken %s-%s arg, but got %d args: %s",
					funcname, d(min), d(max), args.length, Arrays.toString(args)));
		} else if (max != -1 && args.length > max) {
			compileArg.getLogger().log(
					Level.INFO,
					String.format("Function<%s> must be taken %s-%s arg, but got %d args: %s", funcname, d(min),
							d(max), args.length, Arrays.toString(args)));
		}
	}
	
	private String d(int value) {
		return value == -1 ? "" : String.valueOf(value);
	}
}
